<template>
    <div v-for="parent in list" :key="parent.id">
        <el-checkbox v-model="parent.checkAll" :indeterminate="parent.isIndeterminate" @change="allChange(parent)">{{
            parent.name }}</el-checkbox>
        <el-checkbox-group v-model="parent.checkeds" @change="childChange(parent)">
            <el-row>
                <el-col :span="8" v-for="child in parent.children" :key="child.id">
                    <el-checkbox :label="child.id">{{
                        child.name
                    }}</el-checkbox>
                </el-col>
            </el-row>

        </el-checkbox-group>
    </div>
    <div>
        <el-button type="primary" @click="save">保存</el-button>
    </div>
</template>
<script setup lang='ts'>
import { getAllResourceApi, getRoleResourceApi, getAllResourceTypeApi } from '@/api';
import { useRoute } from 'vue-router';
import { ref } from 'vue'
const route = useRoute();
// if(route.query.id) {}
// let categories = ref<IResourceCategoryModel[]>([]);
// let resources = ref<IResourceModel[]>([])
// 要把上面的两个数组组成父子关系，使用双层v-for渲染到页面上 ，所以上面的代码可以不要了
// 请求都是异步的，实现父子关系的时候，是否需要两个数据都回来？是！！！
// 如何保证两个数据都回来？ Promise.all()
// let roleResources = ref<IResourceModel[]>([])

// 构建一个满足父子关系的类型
type IList = IResourceCategoryModel & { children: IResourceModel[], checkAll: boolean, isIndeterminate: boolean, checkeds: number[] }
let list = ref<IList[]>([])

// 所有的资源数据，都放到这里请求
Promise.all([getAllResourceTypeApi(), getAllResourceApi(), getRoleResourceApi(route.query.id as any as number)]).then(res => {
    const [categoryRes, resourceRes, roleResourcesRes] = res;
    if (categoryRes.code === 200 && resourceRes.code === 200 && roleResourcesRes.code === 200) {
        // 构建父子关系
        // 先遍历 1级
        categoryRes.data.forEach(parent => {
            let obj: IList = {
                ...parent,
                checkAll: false,
                isIndeterminate: false,
                checkeds: [],
                children: []
            };
            list.value.push(obj)
            resourceRes.data.forEach(child => {
                if (child.categoryId === parent.id) {
                    obj.children.push(child)
                }
            })
        })

        // 把1级资源的 checkeds 数组，根据角色拥有的 资源，设置一下
        roleResourcesRes.data.forEach(item => {
            list.value.forEach(l => {
                if (l.id === item.categoryId) {
                    // 找到了 角色拥有的 资源的 父级
                    l.checkeds.push(item.id)
                }
                // 这个判断可以减少 -- 自己处理
                l.checkAll = l.checkeds.length === l.children.length;
                l.isIndeterminate = l.checkeds.length > 0 && l.checkeds.length < l.children.length;
            })

        })
    }
})


// 全选的事件
const allChange = (item: IList) => {
    // 点的谁，就要把子级的状态变成和我是一样的
    let ckAll = item.checkAll;
    if (ckAll) {
        // 把所有的子级全选
        item.checkeds = item.children.map(c => c.id);
    } else {
        // 全不选
        item.checkeds = [];
    }
}

// 点击子级
const childChange = (item: IList) => {
    // 子级在点击的时候，还可能会全选
    item.checkAll = item.checkeds.length == item.children.length
    // 判断所有的子级是否勾选大于0个，小于长度个
    item.isIndeterminate = item.checkeds.length > 0 && item.checkeds.length < item.children.length;
}

const save = () => {
    // 发请求
    // 请求要的参数： roleId-  当前的角色的id - route.query.id
    //               resourceIds - 勾选的资源的id
    // let ids: number[] = []
    // list.value.forEach(p => {
    //     p.checkeds.forEach(c => {
    //         ids.push(c)
    //     })
    // })
    // console.log(ids)

    let ids = list.value.reduce<number[]>((prev, current) => {
        prev.push(...current.checkeds)
        return prev;
    }, [])
    console.log(ids)
}
</script>
<style lang="less" scoped></style>